<template>
  <el-dialog title="新增" width="60%" :visible.sync="deShow" :close-on-click-modal="false" append-to-body @close="close">
    <div class="form-box" v-loading="loading">

      <!--基础配置，选择通讯协议接入接出类型-->
      <el-form :model="base" class="report--form-box" :rules="baseRules" label-width="110px" size="small" ref="base">

        <el-row :gutter="20">
          <edit-col
            v-for="(item, index) in typeConfig"
            :span="item.span"
            :key="item.prop+index"
            :prop="item.prop"
            :label="item.label"
            :type="item.type"
            :dictType="item.options ? item.options : ''"
            :dictData="item.optionData"
            :disabled="baseDisabled"
            clearable
            v-model="base[item.prop]"
            @change="changeType"
            :placeholder="`请${item.type === 'input'?'输入':'选择'}${item.label}`"></edit-col>

          <edit-col
            v-if="base.type && base.commType"
            prop="systemCode"
            :label="sysCodeLabel.label"
            type="select"
            :dictData="sysList"
            :dictProps="sysListProps"
            v-model="base.systemCode"
            :disabled="baseDisabled"
            clearable
            @change="changeType"
            :placeholder="`请选择${sysCodeLabel.label}`"></edit-col>
          <edit-col
            v-if="base.type && base.commType === 'IN'"
            prop="groupCode"
            label="服务名称"
            type="select"
            :dictData="groupListBySys"
            :dictProps="grpListProps"
            v-model="base.groupCode"
            :disabled="baseDisabled"
            clearable
            @change="changeType"
            placeholder="请选择服务名称"></edit-col>
        </el-row>

        <el-row type="flex" justify="end" v-show="base.commType && base.type && !showForm">
          <el-form-item>
            <el-button type="primary" @click="createDevice">创建</el-button>
          </el-form-item>
        </el-row>

      </el-form>

      <!--不同类型不同表单配置-->
      <el-form v-if="showForm" :model="form" class="report--form-box" :rules="ruleTest" label-width="110px" size="small" ref="form">

          <div v-for="(item,index) in listData" :key="item.title+index" v-if="item.type !== 'none'">
            <!--HTTP头配置、自定义属性-->
            <el-row v-if="item.type && item.type === 'custom'" :gutter="20">
              <el-col><h4>{{item.title}}</h4></el-col>
              <http-head v-model="form[item.list[0].prop]"></http-head>
            </el-row>

            <el-row v-else :gutter="20">
              <el-col><h4>{{item.title}}</h4></el-col>

              <div v-for="(subItem, subIndex) in item.list">
                <edit-col
                  v-if="subItem.type !== 'none'"
                  :span="subItem.span"
                  :key="subItem.prop+subIndex"
                  :prop="subItem.prop"
                  :label="subItem.label"
                  :type="subItem.type"
                  :maxlength="subItem.maxlength"
                  :showWordLimit="subItem.showWordLimit"
                  :dictType="subItem.options"
                  :dictData="subItem.optionData"
                  v-model="form[subItem.prop]"
                  @change="changeValue"
                  :placeholder="`请${subItem.type === 'select'?'选择':'输入'}${subItem.label}`"></edit-col>

                <!--接包规则-->
                <div v-if="subItem.prop === 'recvRule' && form.recvRule">
                  <edit-col
                    v-for="(recvItem, recvIndex) in recvRule[form.recvRule].list"
                    :key="recvItem.prop+recvIndex"
                    :prop="recvItem.prop"
                    :label="recvItem.label"
                    :type="recvItem.type"
                    :maxlength="subItem.maxlength"
                    :showWordLimit="subItem.showWordLimit"
                    :dictType="recvItem.options"
                    :dictData="recvItem.optionData"
                    v-model="form[recvItem.prop]"
                    :placeholder="`请${subItem.type === 'select'?'选择':'输入'}${recvItem.label}`"></edit-col>
                </div>

              </div>

            </el-row>
          </div>

          <el-row type="flex" justify="end">
            <el-form-item>
              <el-button type="primary" @click="saveData" :loading="save.loading">{{save.text}}</el-button>
            </el-form-item>
          </el-row>

      </el-form>
    </div>

  </el-dialog>
</template>
<script>
  import { save, check, inSysList, outSysList, groupList, putObj } from '@/api/pre/report'
  import { getGroupList,groupCodeAndOut,getGroupListBySysCode } from '@/api/pre/group'
  import formData,{recvRule,typeConfig,typeChange} from './config'
  import mixin from './data.js'
  import editSelect from './select'
  import editCol from './col'
  import httpHead from './http-header'
  export default {
    mixins:[mixin],
    components:{editSelect,editCol,httpHead},
    props: {
      editId: {},
      show: {
        type: Boolean,
        default: false
      },
    },

    data() {
      return {
        useEditId: this.editId,
        deShow: this.show,
        loading: false,
        formAll: formData, //表单配置项
        recvRule, //接包规则配置项
        typeConfig, //四项基础配置：通讯协议、接入接出类型
        typeChange, //四项基础配置：系统名称、服务名称
        ruleForm: {}, //接包规则表单，只用于存字段
        listData: [], //要显示的表单数据
        base: {
          type: '', //通讯协议
          commType: '', //接入接出类型
          systemCode: '', //系统名称
          groupCode: '', //服务名称
        },
        baseBefore:{
          type: '', //通讯协议
          commType: '', //接入接出类型
          systemCode: '', //系统名称
          groupCode: '', //服务名称
        },
        baseDisabled: false,
        sysCodeLabel: {
          label: '项目名称',
          IN: '接入项目名称',
          OUT: '接出项目名称'
        },
        sysList: [], //系统名称列表
        sysListProps: {
          label: 'name',
          value: 'code'
        },
        grpListProps: {
          label: 'name',
          value: 'code'
        },
        groupList: [], //分组列表

        initialForm:{}, //初始表单
        form:{},
        showForm: false, //显示表单所有配置
        groupListBySys: [],//分组列表，通过接入系统查询


        save: {
          loading: false,
          text: '保存',
          defaultText: '保存',
          loadingText: '正在保存'
        },

        ruleTest:{},

      }
    },

    watch: {
      show(val) {
        this.deShow = val
      },
      deShow(val) {
        this.$emit('update:show', val)
        if (!val) {
          Object.assign(this.$data, this.$options.data());
        }
      },
      editId(val){
        this.useEditId = val
      },
      // 'base.type'(val){
      //   if (val === 'custom' && this.base.commType === 'OUT') {
      //     this.$message.error('接出不支持自定义通讯类型，请重新选择')
      //     this.base.commType = ''
      //   }
      // },
      // 'base.commType'(val){
      //   if (val === 'OUT' && this.base.type === 'custom') {
      //     this.$message.error('接出不支持自定义通讯类型，请重新选择')
      //     this.base.type = ''
      //   }
      //   this.base.systemCode = ''
      //   this.base.groupCode = ''
      //
      // }
    },
    created() {

      if (this.useEditId){
        this.getData()
      }
    },
    methods: {
      //获取详情
      getData(){
        check(Object.assign(
            {
              confId: this.useEditId
            }
          )).then(res => {
          this.showForm = true
          this.baseDisabled = true
          let data = res.data.data
          let deviceType = data.commProtocol //通讯协议
          let commType = data.commType //通讯类型 接入接出

          this.listData = this.formAll[commType][deviceType]
          this.listData.forEach( item => {
            if (item.list && item.list.length) {
              item.list.forEach( key => {
                this.$set(this.form, key.prop, key.value)
                this.$set(this.initialForm, key.prop, key.value)

                if (key.rules) this.$set(this.ruleTest, key.prop, key.rules)
              })
            }
          })

          Object.keys(this.form).forEach( key => {
            this.$set(this.form, key, data[key])
            this.$set(this.initialForm, key, data[key])
          })
          Object.keys(this.base).forEach( key => {
            this.$set(this.base, key, data[key])
          })


          if (commType === 'IN') {
            inSysList().then(res => {
              this.sysList = [...res.data.data]
            })

          }else if (commType === 'OUT') {
            outSysList().then(res => {
              this.sysList = [...res.data.data]
            })
          }

          //获取服务名称
          if (commType === 'IN') {
            getGroupListBySysCode(data.systemCode).then(res => {
              this.groupListBySys = [...res.data.data]
            })
          }

          //接包规则
          if (deviceType === 'tcp' && data.recvRule) {
            let recvList = this.recvRule[data.recvRule].list
            let recvFormRule = {}
            recvList.forEach( item => {
              this.$set(this.form,  item.prop, data[item.prop])
              this.$set(this.initialForm,  item.prop, data[item.prop])

              if (item.rules) this.$set(recvFormRule,item.prop, item.rules)
            })
            this.ruleTest = {...this.ruleTest, ...recvFormRule}
          }


        })
      },

      //创建
      createDevice(){

        this.form = {}
        this.initialForm = {}
        this.ruleForm = {}
        this.$refs['base'].validate((valid) => {
          if (!valid) return;

          check(Object.assign(
            {
              systemCode: this.base.systemCode,
              groupCode: this.base.groupCode,
              commType: this.base.commType == "IN" ? 0 : 1,
              commProtocol: this.base.type
            }
          )).then(res => {
            //创建的配置不存在
            if (!res.data.data) {
              this.creatInput()
              return;
            }
            //创建的配置已存在
            this.$confirm('你加载的配置已经存在，确认需要修改吗？', '提示',{
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.useEditId = res.data.data.confId * 1
              this.creatInput(true, res.data.data)
            })
            //   .catch(() => {
            //   this.$message({
            //     type: 'info',
            //     message: '已取消'
            //   });
            // });
          })

        })
      },
      //创建input表单
      creatInput(flag, data){
        let deviceType = this.base.type //通讯协议
        let commType = this.base.commType //通讯类型 接入接出
        this.ruleTest = {}
        this.listData = this.formAll[commType][deviceType]
        this.listData.forEach( item => {
          if (item.list && item.list.length) {
            item.list.forEach( key => {
              this.$set(this.form, key.prop, key.value)
              this.$set(this.initialForm, key.prop, key.value)

              //ruleTest
              if (key.rules) this.$set(this.ruleTest, key.prop, key.rules)
            })
          }
        })

        //如果存在配置
        if (flag) {
          Object.keys(this.form).forEach( key => {
            // this.form[key] = data[key]
            this.$set(this.form, key, data[key])
            this.$set(this.initialForm, key, data[key])
          })

          //接包规则
          if (deviceType === 'tcp' && data.recvRule) {
            let recvList = this.recvRule[data.recvRule].list
            let recvFormRule = {}
            recvList.forEach( item => {
              this.$set(this.form,  item.prop, data[item.prop])
              this.$set(this.initialForm,  item.prop, data[item.prop])

              if (item.rules) this.$set(recvFormRule,item.prop, item.rules)
            })
            this.ruleTest = {...this.ruleTest, ...recvFormRule}
          }
        }
        this.connectFormChange("connetionType")
        this.showForm = true
      },
      //接包规则变化
      changeValue(obj){
        if (obj.prop === "recvRule") {
          this.ruleForm = {}
          let list = this.recvRule[obj.value].list
          let recvFormRule = {}
          if (list && list.length) {
            list.forEach(key =>  {
              this.$set(this.ruleForm, key.prop, key.value)

              if (key.rules) this.$set(recvFormRule,key.prop, key.rules)
            })
            this.ruleTest = {...this.ruleTest, ...recvFormRule}
          }
        }


        //tcp类型选择长连接时多出其他表单
        this.connectFormChange(obj.prop)


      },
      //判断长连接短连接表单变化
      connectFormChange(prop){
        if (this.base.type === 'tcp' && prop === "connetionType"){
          if (this.base.commType == "IN"){
            if (this.form.connetionType === 'long') {
              this.listData[0].list[5].type = 'number'
              this.listData[0].list[6].type = 'number'
              this.listData[3].type = 'show'
            }else if (this.form.connetionType === 'short'){
              this.listData[0].list[5].type = 'none'
              this.listData[0].list[6].type = 'none'
              this.listData[3].type = 'none'
            }
          }else if (this.base.commType == "OUT"){
            if (this.form.connetionType === 'long') {
              this.listData[0].list[6].type = 'number'
              this.listData[3].type = 'show'
            }else if (this.form.connetionType === 'short'){
              this.listData[0].list[6].type = 'none'
              this.listData[3].type = 'none'
            }
          }
        }
      },
      connectFormDelete(params){
        if (this.base.type !== 'tcp') return false;
        if (this.base.commType == "IN" && this.form.connetionType === 'short'){
          delete params.conTimeout
          delete params.backlog
          delete params.interval
          delete params.content
        }else if (this.base.commType == "OUT" && this.form.connetionType === 'short'){
          delete params.backlog
          delete params.interval
          delete params.content
        }
      },
      //基础的四表单变化
      changeType(obj){
        if (this.showForm) {
          let changeForm = JSON.stringify(this.form)
          let initialForm = JSON.stringify(this.initialForm)
          //判断用户是否有修改
          if (changeForm !== initialForm){
            this.$confirm('您修改的内容还未保存，继续操作的话修改的数据将会丢失，是否继续?', '提示',{
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.isChange(obj)
              this.showForm = false

            }).catch(() => {
              this.base[obj.prop] = this.baseBefore[obj.prop]
            });
          }else{
            this.isChange(obj)
            this.baseBefore[obj.prop] = obj.value
            this.showForm = false
          }
        }else{
          this.baseBefore[obj.prop] = obj.value
          this.isChange(obj)
        }

      },
      //四基础项动态添加
      isChange(obj){
        //获取系统名称
        if (obj.prop === 'commType') {
          this.sysCodeLabel.label = this.sysCodeLabel[obj.value]
          if (obj.value === 'IN') {
            inSysList().then(res => {
              this.sysList = [...res.data.data]
            })

          }else if (obj.value === 'OUT') {
            outSysList().then(res => {
              this.sysList = [...res.data.data]
            })
          }

          if (obj.value === 'OUT' && this.base.type === 'custom') {
            this.$message.error('接出不支持自定义通讯类型，请重新选择')
            this.base.type = ''
          }
          this.base.systemCode = ''
          this.base.groupCode = ''

        }

        if (obj.prop === 'type'){
          if (obj.value === 'custom' && this.base.commType === 'OUT') {
            this.$message.error('接出不支持自定义通讯类型，请重新选择')
            this.base.commType = ''
          }
        }

        //获取服务名称
        if (obj.prop === 'systemCode' && this.base.commType === 'IN') {
          if (obj.value) {
            getGroupListBySysCode(obj.value).then(res => {
              this.groupListBySys = [...res.data.data]
              this.base.groupCode = this.groupListBySys[0].code
            })
          }else{
            this.groupListBySys = []
            this.base.groupCode = ''
          }

        }
      },
      //保存
      saveData(){
        this.loadingSave()
        let params = {}
        Object.keys( this.form).map(key =>  params[key] = this.form[key])
        Object.keys( this.ruleForm).map(key =>  params[key] = this.form[key])
        params = Object.assign({},this.base,params)

        this.$refs['form'].validate((valid) => {
          if (!valid) {this.loadedSave(); return;}

          //tcp类型选择连接方式表单会变化的特殊处理，就很烦。
          if (this.base.type === 'tcp'){
            if (this.base.commType === "IN" && this.form.connetionType === 'short'){
              delete params.conTimeout
              delete params.backlog
              delete params.interval
              delete params.content
            }else if (this.base.commType === "OUT" && this.form.connetionType === 'short'){
              delete params.backlog
              delete params.interval
              delete params.content
            }

            //接包规则
            if (this.form.recvRule === 'lengthIdentify' || this.form.recvRule === 'lengthByString'){
              delete params.len
              delete params.endChar
            }else if (this.form.recvRule === 'fixLength' || this.form.recvRule === 'endChar'){
              delete params.maxFrameLength
              delete params.lengthFieldOffset
              delete params.lengthFieldLength
              delete params.lengthAdjustment
              delete params.initialBytesToStrip
              if (this.form.recvRule === 'fixLength') delete params.endChar
              if (this.form.recvRule === 'endChar') delete params.len
            }

          }

          if (this.useEditId){
            params.confId = this.useEditId
            putObj(params).then(response => {
              this.$message.success('通讯配置更新成功！')
              this.$emit('update')
              this.loadedSave();
              this.deShow = false
            })
          }else{
            save(params).then(response => {
              this.$message.success('通讯配置保存成功！')
              this.$emit('update')
              this.loadedSave();
              this.deShow = false
            })
          }
        })



      },

      // 请求中
      loadingSave() {
        this.save.loading = true
        this.save.text = this.save.loadingText
      },
      // 请求完成
      loadedSave() {
        this.save.loading = false
        this.save.text = this.save.defaultText
      },
      close() {
        this.$emit('update:show', false)
      }
    }
  }
</script>
